package com.meringer.entities;

import com.meringer.entities.Road;
import java.io.Serializable;
import java.lang.Long;
import java.lang.String;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

import javax.persistence.*;

/**
 * Entity implementation class for Entity: Race
 *
 */
@Entity
@Table(name="T_RACES")

public class Race implements Serializable
{
	private static final long serialVersionUID = 1L;

	   
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	@Column(name="RACE_ID", nullable=false)
	private Long raceID;
	
	@Column(name="RACE_DATETIME", nullable=false)
	@Temporal(TemporalType.TIMESTAMP)
	private Date raceTime;
	
    @ManyToOne
	@JoinColumn(name="ROAD_ID", nullable=false)
	private Road road;
        
    @ManyToMany(mappedBy="races")
	private List<User> contestants;
    
    @Column(name="DESCRIPTION", length = 150)
	private String description;
    
    @OneToMany(mappedBy="race", cascade=CascadeType.ALL)
    private List<RaceResult> raceResults;
	
	public Race() {
		super();
	}   
	
	
	public Race(Road road, String description) {
		super();
		this.road = road;
		this.description = description;
	}


	public Long getRaceID() {
		return this.raceID;
	}

	public void setId(Long raceID) {
		this.raceID = raceID;
	}   
	public Date getRaceTime() {
		return this.raceTime;
	}

	public Road getRoad() {
		return this.road;
	}

	public void setRoad(Road road) {
		this.road = road;
	}   
	public String getDescription() {
		return this.description;
	}

	public void setDescription(String description) {
		this.description = description;
	}   
	public List<User> getContestants() {
		return this.contestants;
	}

	public void setContestants(List<User> contestants) {
		this.contestants = contestants;
	}
	public void setRaceID(Long raceID) {
		this.raceID = raceID;
	}
	public void setRaceTime(Date raceTime) {
		this.raceTime = raceTime;
	}
	public List<RaceResult> getRaceResults() {
		return raceResults;
	}
	public void setRaceResults(List<RaceResult> raceResults) {
		this.raceResults = raceResults;
	}
	
	/**
	 * Get the sorted list of race results depending on the contestant's standings
	 */
	public List<RaceResult> getSortedRaceResults()
	{
		if (this.raceResults == null)
			return null;
		Collections.sort(this.raceResults, new Comparator<RaceResult>() {
			public int compare(RaceResult r1, RaceResult r2){
				return (r1.getTime()>r2.getTime() ? 1 :
							(r1.getTime()==r2.getTime() && 
							 r1.getUser().getExperience()>r2.getUser().getExperience() ? 1 : -1)); 
			}
		});
		
		return this.raceResults;
	}
	
	@Override
	public boolean equals(Object obj)
	{
		if (obj != null && obj instanceof Race && ((Race)obj).getRaceID() != null)
			return ((Race)obj).getRaceID().equals(this.raceID);
		return false;
	}
}
